package com.example.utils;

import com.example.entity.RegionStats;
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVParser;
import org.apache.commons.csv.CSVRecord;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.http.RequestEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;

import java.io.*;
import java.net.URI;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

/**
 * @author junqiancai@foxmail.com
 * @since 2021/5/15 14:48
 * 包含数据的获取和解析，以及封装成一个单例的对象
 */
public class DataObject {
    //单例对象dataList,包括所以的对象
    private static List<RegionStats> dataList;

    //使用克隆的gitee文件地址
    private static final String CSV_DATA_URL = "https://gitee.com/dgut-sai/COVID-19/raw/master/" +
            "csse_covid_19_data/csse_covid_19_time_series/time_series_covid19_confirmed_global.csv";
    //使用克隆的github上的文件地址
    private static final String CSV_DATA_URL_IN_GITHUB = "https://raw.githubusercontent.com/CSSEGISandData/COVID-19/master/" +
            "csse_covid_19_data/csse_covid_19_time_series/time_series_covid19_confirmed_global.csv";

    public static List<RegionStats> getVirusConfirmedList(){
        return dataList;
    }

    //表示获取数据到dataList中，调用下方的方法
    public static void fetchConfirmedDataInInternet() throws IOException {
//        Reader reader = getMockMsgFromFile();
        Reader reader = getCsvReader();
        dataList = resolveCvs(reader);
    }

    //开发过程先用本地文件，避免频繁网络请求
    private static Reader getMockMsgFromFile(){
        ClassPathResource classPathResource = new ClassPathResource("time_series_covid19_confirmed_global.csv");
        try {
            return new FileReader(classPathResource.getFile());
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    //从网络上获取csv格式数据，并转换为Reader
    private static Reader getCsvReader(){
        RequestEntity<Void> requestEntity = RequestEntity.get(URI.create(CSV_DATA_URL_IN_GITHUB))
                .headers(httpHeaders -> httpHeaders.add("User-Agent","Mozilla/5.8"))
                .build();
        ResponseEntity<Resource> exchange = new RestTemplate().exchange(requestEntity,Resource.class);
        Resource body = exchange.getBody();
        try {
            return body==null?null:new InputStreamReader(body.getInputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    //使用CSVFormat解析获取到的reader
    private static List<RegionStats> resolveCvs(Reader reader) throws IOException {
        if(reader==null)throw new IOException("reader数据为null");
        List<RegionStats> regionStatsList = new LinkedList<>();//保存每一行
        CSVParser csvParser = CSVFormat.DEFAULT.withFirstRecordAsHeader().parse(reader);
        List<String> headers = csvParser.getHeaderNames();  //获取表头
        List<CSVRecord> records = csvParser.getRecords();
        for (CSVRecord record : records) {
            RegionStats t = constructRegionStats(headers, record);   //把表头和对应的一行记录传入
            regionStatsList.add(t);
        }
        return regionStatsList;
    }

    //根据表头和一行数据构造一个对象
    private static RegionStats constructRegionStats(List<String> headers, CSVRecord record) {
        RegionStats regionStats = new RegionStats().setDateList(new ArrayList<>()).setAmountList(new ArrayList<>());
        headers.forEach(it->{
            String val = record.get(it);
            try {   //数据中有部分经纬度有问题,todo：是否抛弃经纬度异常的行，目前不抛弃
                switch (it){
                    case "Province/State":regionStats.setState(val);break;
                    case "Country/Region":regionStats.setCountry(val);break;
                    case "Lat":regionStats.setLatitude(Double.parseDouble(val));break;
                    case "Long":regionStats.setLongitude(Double.parseDouble(val));break;
                    default:{
                        regionStats.getDateList().add(it);
                        regionStats.getAmountList().add(Integer.valueOf(val));
                    }
                }
            }
            catch (NumberFormatException e){
                System.out.println("存在部分经纬度数据格式不正确");
            }
        });
        ArrayList<Integer> amountList = regionStats.getAmountList();
        //设置最新确诊数
        int latest = amountList.get(amountList.size() - 1);
        regionStats.setLatestTotalCases(latest);
        //计算昨日新增
        int yesterday = amountList.get(amountList.size() - 2);
        regionStats.setDiffFromPrevDay(latest-yesterday);
        return regionStats;
    }

    public static void main(String[] args) throws IOException {
        //先从文件读取 用于测试
        File file = new File("E:\\TempStore\\assignment\\JavaPro\\springboot-lab3\\src\\main\\resources\\time_series_covid19_confirmed_global.csv");
        FileReader reader = new FileReader(file);
        resolveCvs(reader);
    }
}
